package com.fg.cloud.manager.service.factory.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fg.cloud.common.NumberUtil;
import com.fg.cloud.common.PageUtils;
import com.fg.cloud.manager.entry.BaseEntity;
import com.fg.cloud.manager.entry.factory.FactoryStatementDetails;
import com.fg.cloud.manager.entry.factory.FactoryStatementEntity;
import com.fg.cloud.manager.entry.order.OrderPaymentEntity;
import com.fg.cloud.manager.mapper.BaseMapper;
import com.fg.cloud.manager.mapper.agency.AgencyBillMapper;
import com.fg.cloud.manager.mapper.factory.FactoryStatementMapper;
import com.fg.cloud.manager.service.BaseServiceImpl;
import com.fg.cloud.manager.service.factory.FactoryStatementService;

/**
 * Description:厂商对账单ServiceImpl
 * 
 * @author shaoqiping
 * @date 2017年8月28日下午4:18:45
 */
@Service
public class FactoryStatementServiceImpl extends BaseServiceImpl implements FactoryStatementService {

	@Autowired
	private FactoryStatementMapper statementMapper;
	@Autowired
	private AgencyBillMapper billMapper;

	@Override
	protected <T extends BaseEntity> BaseMapper getBaseMapper() {
		return null;
	}

	@Override
	public void findList(PageUtils<FactoryStatementEntity> pageinfo) {
		long total = statementMapper.filterCount(pageinfo.getCondition());
		pageinfo.setTotal(total);
		if (total > 0) {
			pageinfo.setData(statementMapper.findList(pageinfo));
		} else {
			pageinfo.setData(new ArrayList<FactoryStatementEntity>());
		}
	}

	@Override
	public List<FactoryStatementDetails> findDetails(Long id, Long facId) {
		FactoryStatementEntity statementEntity = statementMapper.selectByPrimaryKey(id);
		if (statementEntity.getFacId() != facId) {
			return null;
		}
		BigDecimal oldAmount = statementEntity.getOldAmount();
		List<FactoryStatementDetails> statement = statementMapper.selectDetails(statementEntity);
		if(statement.size()>0){
			for (FactoryStatementDetails temp : statement) {
				temp.setType(1);
			}
		}
		List<FactoryStatementDetails> flows = statementMapper.selectFlows(statementEntity);
		for (FactoryStatementDetails temp : flows) {
			if (temp.getTransInfo() == 1) {
				temp.setType(3);
			} else if (temp.getTransInfo() == 2) {
				temp.setType(5);
			} else {
				temp.setType(4);
			}
		}
		statement.addAll(flows);
		// 按时间快速排序
		Collections.sort(statement, new Comparator<FactoryStatementDetails>() {
			@Override
			public int compare(FactoryStatementDetails o1, FactoryStatementDetails o2) {
				return o1.getTime().compareTo(o2.getTime());
			}
		});

		for (int i = 0; i < statement.size(); i++) {
			FactoryStatementDetails element = statement.get(i);
			if (element.getType() == 1) {
				oldAmount = oldAmount.subtract(element.getDeliveryMoney());
				element.setBalance(oldAmount);
				BigDecimal temp = element.getAmountTotal().subtract(element.getAmountPay())
						.multiply(element.getDeliveryMoney().divide(element.getAmountTotal(),6,BigDecimal.ROUND_HALF_UP));
				if (temp.compareTo(new BigDecimal(0)) > 0) {
					FactoryStatementDetails discount = new FactoryStatementDetails();
					discount.setTime(element.getTime());
					discount.setOrderId(element.getOrderId());
					discount.setOrderNo(element.getOrderNo());
					discount.setDiscount(temp);
					discount.setType(2);
					oldAmount = oldAmount.add(temp);
					discount.setBalance(oldAmount);
					statement.add(i + 1, discount);
				}
				if(element.getExpressFee().compareTo(BigDecimal.ZERO)>0){
					BigDecimal fee=element.getExpressFee().multiply(element.getDeliveryMoney().divide(element.getAmountTotal(),6,BigDecimal.ROUND_HALF_UP));
					FactoryStatementDetails expressFee = new FactoryStatementDetails();
					expressFee.setTime(element.getTime());
					expressFee.setOrderId(element.getOrderId());
					expressFee.setOrderNo(element.getOrderNo());
					expressFee.setDeliveryMoney(fee);;
					expressFee.setType(6);
					oldAmount = oldAmount.subtract(fee);
					expressFee.setBalance(oldAmount);
					statement.add(i + 1, expressFee);
				}
			
			}
			if (element.getType() >= 3&&element.getType() < 6) {
				if (element.getPaymentType() != 5) {
					oldAmount = oldAmount.add(element.getPayment());
					element.setBalance(oldAmount);
				} else {
					element.setBalance(oldAmount);
				}
			}
		}
		return statement;
	}

	@Override
	@Transactional
	public boolean createStatement(FactoryStatementEntity statementEntity) {
		FactoryStatementEntity oldEntity = statementMapper.selectLastOne(statementEntity.getFacId(),
				statementEntity.getAgeId());
		if (oldEntity == null) {
			statementEntity.setOldAmount(new BigDecimal(0));
			statementEntity.setParentId(0L);
		} else {
			statementEntity.setOldAmount(oldEntity.getNewAmount());
			statementEntity.setParentId(oldEntity.getId());
		}
		BigDecimal oldAmount = statementEntity.getOldAmount();
		List<FactoryStatementDetails> statement = statementMapper.selectDetails(statementEntity);
		if(statement.size()>0){
			for (FactoryStatementDetails temp : statement) {
				temp.setType(1);
			}
		}
		List<FactoryStatementDetails> flows = statementMapper.selectFlows(statementEntity);
		for (FactoryStatementDetails temp : flows) {
			if (temp.getTransInfo() == 1) {
				temp.setType(3);
			} else if (temp.getTransInfo() == 2) {
				temp.setType(5);
			} else {
				temp.setType(4);
			}
		}
		statement.addAll(flows);
		// 按时间快速排序
		Collections.sort(statement, new Comparator<FactoryStatementDetails>() {
			@Override
			public int compare(FactoryStatementDetails o1, FactoryStatementDetails o2) {
				return o1.getTime().compareTo(o2.getTime());
			}
		});
		for (int i = 0; i < statement.size(); i++) {
			FactoryStatementDetails element = statement.get(i);
			if (element.getType() == 1) {
				oldAmount = oldAmount.subtract(element.getDeliveryMoney());
				element.setBalance(oldAmount);
				BigDecimal temp = element.getAmountTotal().subtract(element.getAmountPay())
						.multiply(element.getDeliveryMoney().divide(element.getAmountTotal(),6,BigDecimal.ROUND_HALF_UP));
				if (temp.compareTo(BigDecimal.ZERO) > 0) {
					FactoryStatementDetails discount = new FactoryStatementDetails();
					discount.setType(2);
					oldAmount = oldAmount.add(temp);
					discount.setBalance(oldAmount);
					statement.add(i + 1, discount);
				}
				if(element.getExpressFee().compareTo(BigDecimal.ZERO)>0){
					BigDecimal fee=element.getExpressFee().multiply(element.getDeliveryMoney().divide(element.getAmountTotal(),6,BigDecimal.ROUND_HALF_UP));
					FactoryStatementDetails expressFee = new FactoryStatementDetails();
					expressFee.setType(6);
					oldAmount = oldAmount.subtract(fee);
					expressFee.setBalance(oldAmount);
					statement.add(i + 1, expressFee);
				}
			}
			if (element.getType() >= 3&&element.getType() < 6) {
				if (element.getPaymentType() != 5) {
					oldAmount = oldAmount.add(element.getPayment());
					element.setBalance(oldAmount);
				} else {
					element.setBalance(oldAmount);
				}
			}
		}
		if (statement.size() == 0) {
			statementEntity.setNewAmount(oldAmount);
		} else {
			statementEntity.setNewAmount(statement.get(statement.size() - 1).getBalance());
		}
		//编码规则
		statementEntity.setStatementNum(NumberUtil.getStatementNumber());
		return statementMapper.insertSelective(statementEntity) > 0;
	}

	@Override
	@Transactional
	public boolean modify(FactoryStatementEntity entity) {
		return statementMapper.update(entity) > 0;
	}

	@Override
	public FactoryStatementEntity findLastOne(Long facId, Long ageId) {
		return statementMapper.selectLastOne(facId, ageId);
	}

	@Override
	@Transactional
	public boolean remove(Long id) {
		return statementMapper.deleteStatement(id)>0;
	}

	@Override
	public List<OrderPaymentEntity> findPayments(Long id) {
		return billMapper.selectPays(id);
	}

	@Override
	@Transactional
	public boolean deleteStatement(Long facId) {
		return statementMapper.delByfacId(facId) > 0 ? true : false;
	}
}
